package com.i2863.shiroDemo.config;

import com.i2863.shiroDemo.dto.ResultInfo;
import com.i2863.shiroDemo.ex.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.redis.connection.PoolException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.servlet.ServletException;

/**
 * @author cexy
 * @date 2019/8/20 14:53
 * @description: 全局异常处理
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseBody
    public ResultInfo<Boolean> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        log.error("参数解析失败！cause by:{}", e.getMessage());
        return new ResultInfo<>(400, "参数解析失败！");
    }

    /**
     * 405 - Method Not Allowed
     */
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    @ResponseBody
    public ResultInfo<Boolean> handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        log.error("不支持当前请求方法！cause by:{}", e.getMessage());
        return new ResultInfo<>(405, "不支持当前请求方法！");
    }

    /**
     * 415 - Unsupported Media Type
     */
    @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    @ResponseBody
    public ResultInfo<Boolean> handleHttpMediaTypeNotSupportedException(
            HttpMediaTypeNotSupportedException e) {
        log.error("不支持当前媒体类型！cause by:{}", e.getMessage());
        return new ResultInfo<>(415, "不支持当前媒体类型！");
    }

    /**
     * 500 - Internal Server Error
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    public ResultInfo<Boolean> handleException(BusinessException e) {
        return new ResultInfo<>(500, e.getMessage());
    }

    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(ServletException.class)
    @ResponseBody
    public ResultInfo<Boolean> handleException(ServletException e) {
        return new ResultInfo<>(500,e.getMessage());
    }

    /**
     * 403 - 没有权限
     */
    @ResponseStatus(HttpStatus.FORBIDDEN)
    @ExceptionHandler(UnauthorizedException.class)
    @ResponseBody
    public ResultInfo<Boolean> handleUnauthorizedException(UnauthorizedException e) {
        log.warn("没有权限！cause by:{}", e.getMessage());
        return new ResultInfo<>(403, "没有权限！");
    }

/*    @ResponseStatus(HttpStatus.FORBIDDEN)
    @ExceptionHandler({UnauthorizedException.class, AuthorizationException.class})
    public String unauthorizedRole() {
        log.warn("------没有权限-------");
        return "error/403";
    }*/

    @ExceptionHandler(DuplicateKeyException.class)
    public ResultInfo<Boolean> handleDuplicateKeyException(DuplicateKeyException e) {
        log.error("------" + e.getMessage() + "-------");
        return new ResultInfo<>("数据库中已存在该记录");
    }

    @ExceptionHandler(PoolException.class)
    public ResultInfo<Boolean> handlePoolException(PoolException e) {
        log.warn("------" + e.getMessage() + "-------");
        return new ResultInfo<>("Redis 连接异常!");
    }
}